import {
  Component,
  OnInit,
  OnDestroy,
  EventEmitter,
  ElementRef,
  ViewChild,
  AfterViewChecked
} from '@angular/core';
import { Observable } from "rxjs/Observable";
import { Subject } from "rxjs/Subject";
import { ReplaySubject } from "rxjs/ReplaySubject";
import { Subscription } from "rxjs/Subscription";
import { async } from "rxjs/scheduler/async";
import { CmHttp } from "./../../http-module/http.service";
import { DB_ARTICLE_STORE_NAME, DB_NAME, getStockTypeThree, STOCK_TYPE } from "utils";
import { SummaryNameService, STOCKURL } from "shared";

export interface InfoSourceParams {
  $type: string;
  symbol: string;
}

@Component({
  // moduleId: module.id,
  selector: 'info-list',
  templateUrl: 'info-list.component.html',
  styleUrls: [
    "info-list.component.less",
    "../../stock/stock-combo/stock-combo.info-list.component.less"
  ],
  inputs: [
    "appendClass",
    "stockSource",
    "infoType",
    "cache",
    "hrefRef"
  ],
  outputs: [
    "entryClick"
  ]
})
export class InfoListComponent implements OnInit, AfterViewChecked, OnDestroy {
  private static perPage = 10;
  page = 1;
  startId = 0;
  infoList = [];
  infoType;
  hrefRef;
  stock;
  isLoading = false;
  // cache = false;
  // db: IDBDatabase;
  @ViewChild("detective", { read: ElementRef })
  detective: ElementRef;
  entryClick = new EventEmitter();
  downloadSub = new EventEmitter();
  subscription: Subscription;
  downloadScription: Subscription;
  stockSource: Observable<InfoSourceParams>;
  infoListSub = new ReplaySubject(1);
  marketDbs;

  constructor(private http: CmHttp, private sns: SummaryNameService) { }

  ngOnInit() {
    let { stockSource, http } = this;

    // 过滤指数和板块的股票数据
    Observable.combineLatest(
      stockSource,
      this.sns.summaryNameSub,
      (stock, db: Array<any>) => {
        console.debug("this.marketDbs.length: ", db.length);
        this.stock = stock;
        db.forEach(a => {
          if (a.symbol === stock.symbol) {
            this.stock.market = a.market;
            return;
          }
        });
        return this.stock;
      })
      .filter(res => res.symbol && res.market)
      .subscribe(res => {
        console.debug("info-list stock: ", res);
        if (getStockTypeThree(res) === STOCK_TYPE.STOCK) {
          console.debug("info-list Stock Type: ", res)
          this.infoListSub.next(res);
        }
      });
    // 获取数据
    this.infoListSub.subscribe(res => console.debug("INfo list subsc: ", res));
    this.infoListSub
      .switchMap(req => {
        console.debug("info-list REQ: ", req);
        this.page = 1;
        return http.get(`${STOCKURL}/api/v2/sc/stocks/${req["symbol"]}/${(req["$type"] || this.infoType)}?page=${this.page}&perPage=${InfoListComponent.perPage}`, {}, {cacheAge: http.CACHE_AGE.Hour})
          .catch(err => {
            console.error("InfoList Error: ", err);
            return Observable.of([])
          })
      })
      .subscribe(infoList => {
        console.debug("Info List: infolist get: ", infoList);
        if (infoList && infoList.data.length) {
          infoList = infoList.data;
          this.infoList = <any[]>infoList;
          this.startId = infoList.slice(-1)[0]["id"];
          this.page++;
          this.tryLoadMore();
        } else {
          this.startId = 0;
          this.page = 1;
        }
        this.isLoading = false;

        // 数据库部分 暂时注销
        // let transaction: IDBTransaction = this.db.transaction(DB_ARTICLE_STORE_NAME, "readwrite");
        // transaction.oncomplete = e => console.debug("Update DB Done", e);
        // transaction.onerror = e => console.debug("Update DB Error", e);
        // let objectStore = transaction.objectStore(DB_ARTICLE_STORE_NAME);
        // this.infoList.forEach(entry => objectStore.put(entry));
        if (this.downloadScription) {
          this.downloadScription.unsubscribe();
          this.downloadScription = undefined;
        }
        this.downloadScription = (
          this.downloadSub
            .debounceTime(200)
            .switchMap(() => {
              this.isLoading = true;
              return http.get(
                `${STOCKURL}/api/v2/sc/stocks/${this.stock["symbol"]}/${this.infoType}?perPage=${InfoListComponent.perPage}&page=${this.page}`, {}, {cacheAge: http.CACHE_AGE.Hour}
              )
            })
            .subscribe(infoList => {
              this.isLoading = false;
              // console.debug("InfoList: load more list done:", infoList);
              if (!infoList || !infoList.data.length) {
                this.page = 1;
                this.startId = 0
                return this.downloadScription.unsubscribe();
              }
              infoList = infoList.data
              this.page++;
              this.startId = infoList.slice(-1)[0]["id"];
              this.infoList = [...this.infoList, ...infoList];
            })
        );
        this.tryLoadMore()
      });



    // IndexedDB 部分 暂时注销
    // if (!window.indexedDB) throw new Error("Your browser is not support Cache");
    // let req: IDBOpenDBRequest = indexedDB.open(DB_NAME, 2);
    // req.onerror = e => console.error("Open DB Error: ", e.target);
    // req.onsuccess = e => {
    //   let db: IDBDatabase = this.db = (e.target as IDBRequest).result;

    // };
    // req.onupgradeneeded = e => {
    //   console.debug("IDB Upgrade");
    //   let db: IDBDatabase = this.db = (e.target as IDBRequest).result;
    //   let objectStore = db.createObjectStore(DB_ARTICLE_STORE_NAME, {
    //     keyPath: "id"
    //   }).createIndex("stock_code", "stock_code", { unique: false });
    // }
  }

  ngAfterViewChecked() {
    // console.debug("InfoList View Checked: ", this, Math.floor(Math.random() * 20));
    // if (this.isDetectiveExist() && !this.isLoading && this.downloadScription) {
    //   // console.debug("InfoList: ", "Need to load more", this.infoList);
    //   this.downloadSub.next(true);
    //   this.isLoading = true;
    // }

  }

  tryLoadMore() {
    if (this.isDetectiveExist() && this.downloadScription) {
      // console.debug("InfoList: ", "Need to load more", this.infoList);
      this.downloadSub.next(true);
    }
  }

  ngOnDestroy() {
    if (this.subscription) {
      this.subscription.unsubscribe();
    }
    if (this.downloadScription) {
      this.downloadScription.unsubscribe();
    }
  }

  onScrollHandler(e: WheelEvent) {

    this.tryLoadMore();
  }

  isDetectiveExist() {
    if (!this.detective) return false;
    let detectiveElem: HTMLElement = this.detective.nativeElement;
    let parentElem = detectiveElem.parentElement;
    let top = detectiveElem.getBoundingClientRect().top;
    let parentRect = parentElem.getBoundingClientRect();
    return (top >= parentRect.top && top <= parentRect.bottom);
  }


  onClick(entry) {
    this.entryClick.next(entry);
  }

  getHref(entry) {
    return this.hrefRef ? `${this.hrefRef}?symbol=${this.stock.symbol}&type=${this.infoType}&id=${entry.id}` : "javascript:;";
  }
}